<?php

namespace app\api\Logic;


use app\api\Logic\Campusclass\CampusClassCourseArrangingLogic;
use app\api\Logic\Campusclass\CampusClassDateRecordLogic;
use app\api\Logic\Campusclass\CampusClassLogic;
use app\api\Logic\Course\OrderSublevelLogic;
use app\api\model\ManystoreShopSettingModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

class ManystoreShopSettingLogic
{
    /**
     * 获取校区约课规格
     * @param $shopId
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function ruleInfo($shopId){
        $info = ManystoreShopSettingModel::where('shop_id',$shopId)->find();
        return objToArray($info) ?? [];
    }

    /**
     * 根据约课规则验证学院是否允许约课
     * @param $shopId
     * @param $userId
     * @param $classCourseDateInfo
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException|Exception
     */
    public function verifyRule($shopId,$userId,$classCourseDateInfo){
        if(empty($classCourseDateInfo)){
            return false;
        }

        $dateRecordLogic = new CampusClassDateRecordLogic();
        $classLogic = new CampusClassLogic();
        $orderSublevelLogic = new OrderSublevelLogic();
        $campusClassCourseArranging = new CampusClassCourseArrangingLogic();

        //获取后台排课信息
        $arrangingInfo = $campusClassCourseArranging->getInfo($classCourseDateInfo['a_id']);
        //排课信息为空或者不可约课，则不允许预约
        if(empty($arrangingInfo) || $arrangingInfo['is_set'] == 0){
            return false;
        }

        $time = time();

        //获取学员预约本次班课记录
        $recordList = $dateRecordLogic->getRecordList(['user_id' => $userId,'date_id' => $classCourseDateInfo['id'],'status' => 1]);

        //获取约课规则
        $ruleInfo = $this->ruleInfo($shopId);
        if(!empty($ruleInfo)){
            //开始预约时间限制规则
            if($ruleInfo['appointment_start_type'] == 2){
                //限制提前多少小时
                if(($ruleInfo['appointment_start_num'] > 0 && ($classCourseDateInfo['start_time'] - $ruleInfo['appointment_start_num'] * 3600) < $time) || $ruleInfo['appointment_start_num'] <= 0){
                    //若提前小时数大于0并且上课开始时间-提前小时数小于当前时间或者提前小时数小于等于0，则表示可预约时间未满足
                    return false;
                }
            }else if($ruleInfo['appointment_start_type'] == 3){
                //限制提前多少天
                if(($ruleInfo['appointment_start_num'] > 0 && ($classCourseDateInfo['start_time'] - $ruleInfo['appointment_start_num'] * 86400) < $time) || $ruleInfo['appointment_start_num'] <= 0){
                    //若提前天数大于0并且上课开始时间-提前天数小于当前时间或者提前天数小于等于0，则表示可预约时间未满足
                    return false;
                }
            }

            //截止预约时间限制规则
            if($ruleInfo['appointment_befor_type'] == 2){
                //限制上课前多少小时不可预约
                if(($ruleInfo['appointment_befor_num'] > 0 && ($time + $ruleInfo['appointment_befor_num'] * 3600) > $classCourseDateInfo['start_time']) || $ruleInfo['appointment_befor_num'] <= 0){
                    //若截止小时数大于0并且当前时间+截止小时数大于上课时间或者截止小时数小于等于0，则表示可预约时间未满足
                    return false;
                }
            }else if($ruleInfo['appointment_befor_type'] == 3){
                //限制上课前多少分钟不可预约
                if(($ruleInfo['appointment_befor_num'] > 0 && ($time + $ruleInfo['appointment_befor_num'] * 60) > $classCourseDateInfo['start_time']) || $ruleInfo['appointment_befor_num'] <= 0){
                    //若截止小时数大于0并且当前时间+截止分钟数大于上课时间或者截止分钟数小于等于0，则表示可预约时间未满足
                    return false;
                }
            }else if($ruleInfo['appointment_befor_type'] == 4){
                //限制上课前指定时间不可预约
                if($ruleInfo['appointment_befor_num'] > 0 || !empty($ruleInfo['appointment_befor_time'])){
                    $day = $ruleInfo['appointment_befor_num'] ?? 0;
                    $hour = $ruleInfo['appointment_befor_time'] ?? '';
                    $tempTime = $time;
                    if($day > 0){
                        $tempTime = $classCourseDateInfo['start_time'] - ($day * 86400);
                    }
                    if(!empty($hour)){
                        $tempTime = strtotime(date('Y-m-d '.$hour,$tempTime));
                    }
                    if($time >= $tempTime){
                        return false;
                    }
                }else if($ruleInfo['appointment_befor_num'] <= 0 && empty($ruleInfo['appointment_befor_time'])){
                    //或者指定天数和指定时分都为空，则表示不可预约
                    return false;
                }
            }

            //预约次数限制
            if($ruleInfo['appointment_type'] == 2){
                //次数限制
                if(count($recordList) >= $ruleInfo['appointment_num']){
                    return false;
                }
            }else if($ruleInfo['appointment_type'] > 2){
                //周期限制
                if($ruleInfo['appointment_type'] == 3){
                    //按天限制
                    $startTime = strtotime(date('Y-m-d'));
                    $endTime = $startTime + 86400 - 1;
                }else if($ruleInfo['appointment_type'] == 4){
                    $defaultDate = date('Y-m-d');
                    $week = date('w',$time);
                    //按周限制
                    $startTime= strtotime(date('Y-m-d',strtotime("$defaultDate -".($week ? $week - 1 : 6).' days')));
                    $endTime = strtotime(date('Y-m-d 23:59:59',strtotime("$startTime +6 days")));
                }else if($ruleInfo['appointment_type'] == 5){
                    //按月限制
                    $startTime = strtotime(date('y-m-d h:i:s', mktime(0,0,0,date('m'),1,date('y'))));
                    $endTime = strtotime(date('y-m-d h:i:s', mktime(23,59,59,date('m'),date('t'),date('y'))));
                }
                $recordList = $dateRecordLogic->getRecordList(['user_id' => $userId,'date_id' => $classCourseDateInfo['id'],'status' => 1,'start_time' => $startTime,'end_time' => $endTime]);
                if(count($recordList) >= $ruleInfo['appointment_num']){
                    return false;
                }
            }

            //最低课时限制
            if($ruleInfo['appointment_min_type'] > 0){
                //获取学员在该班级下的最高课时
                $myMaxCourseHour = $orderSublevelLogic->getMaxCourseHourByClassId($shopId,$userId,$classCourseDateInfo['class_id']);
                if($myMaxCourseHour['course_hour_type'] == 'hour'){
                    //仅当学员剩余课时为时类型时才需判断课时数是否充足，若为天或者月，则必然满足课时要求
                    if($ruleInfo['appointment_min_type'] == 1){
                        //获取授课课时
                        $getClassInfo = $classLogic->getInfo($shopId,$classCourseDateInfo['class_id']);
                        $classHour = $getClassInfo['class_hour'] ?? 0;
                        if($myMaxCourseHour['course_hour'] < $classHour){
                            return false;
                        }
                    }else if($ruleInfo['appointment_min_type'] == 2 && $myMaxCourseHour['course_hour'] < $ruleInfo['appointment_min_num']){
                        return false;
                    }
                }
            }
        }

        return true;
    }

    /**
     * 根据约课规则验证学员是否允许取消预约
     * @param $shopId
     * @param $userId
     * @param $signInfo
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function cancelVerifyRule($shopId,$signInfo){
        if(empty($classCourseDateInfo)){
            return false;
        }

        $time = time();

        //获取约课规则
        $ruleInfo = $this->ruleInfo($shopId);
        if(!empty($ruleInfo)){
            //取消预约时间限制规则
            if($ruleInfo['appointment_cancel_type'] == 2){
                //限制上课前多少小时不可取消预约
                if(($ruleInfo['appointment_cancel_num'] > 0 && ($time + $ruleInfo['appointment_cancel_num'] * 3600) > $signInfo['start_time']) || $ruleInfo['appointment_cancel_num'] <= 0){
                    //若取消预约小时数大于0并且当前时间+截止小时数大于上课时间或者截止小时数小于等于0，则表示不可取消预约
                    return false;
                }
            }else if($ruleInfo['appointment_cancel_type'] == 3){
                //限制上课前多少分钟不可取消预约
                if(($ruleInfo['appointment_cancel_num'] > 0 && ($time + $ruleInfo['appointment_cancel_num'] * 60) > $signInfo['start_time']) || $ruleInfo['appointment_cancel_num'] <= 0){
                    //若截止分钟数大于0并且当前时间+截止分钟数大于上课时间或者截止分钟数小于等于0，则表示不可取消预约
                    return false;
                }
            }else if($ruleInfo['appointment_cancel_type'] == 4){
                //限制上课前指定时间不可取消预约
                if($ruleInfo['appointment_cancel_num'] > 0 || !empty($ruleInfo['appointment_cancel_time'])){
                    $day = $ruleInfo['appointment_cancel_num'] ?? 0;
                    $hour = $ruleInfo['appointment_cancel_time'] ?? '';
                    $tempTime = $time;
                    if($day > 0){
                        $tempTime = $signInfo['start_time'] - ($day * 86400);
                    }
                    if(!empty($hour)){
                        $tempTime = strtotime(date('Y-m-d '.$hour,$tempTime));
                    }
                    if($time >= $tempTime){
                        return false;
                    }
                }else if($ruleInfo['appointment_cancel_num'] <= 0 && empty($ruleInfo['appointment_cancel_time'])){
                    //或者指定天数和指定时分都为空，则表示不可预约
                    return false;
                }
            }
        }

        return true;
    }
}
